home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Merciful 2
/
Merciful - Disc 2.iso
/
software
/
d
/
dialupv3.06.lha
/
dialup
/
dialup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-30
|
16KB
|
466 lines
#include "dialup.h"
static const char version[] = "$VER: Dialup 3.06 (30.1.96)";
BPTR mystderr = NULL;
const UBYTE *prgname = NULL;
struct IOExtSer *serialIOReq = NULL;
struct timerequest *timereq = NULL;
BPTR repfile = NULL;
UBYTE *rxbuffer = NULL;
LONG arg[A_ALL + 1];
struct argspec argtab[] = {
"COMMAND=CMD", (LONG)"TOGGLE" , /* only TOGGLE */
"PHONENUMBER=PN/K/M", NULL , /* ptr to PN *array* init later */
"REDIALDELAY=RDD/K/N", (LONG)"\0\0\0\xB4" , /* Delay for *same* number 180s */
"MODEMCONNECTTIME=MCT/K/N", (LONG)"\0\0\0\x3D" , /* Time to connect 61s */
"RINGS=RGS/K/N", (LONG)"\0\0\0\x01" , /* AUTOANSWER after 1 RING */
"WAITBEFORWUS=WBW/K/N", (LONG)"\0\0\0\x03" , /* Wait befor sending WUS */
"WAKEUPSTRING=WUS/K", NULL , /* String to sent to get a ogin:*/
"LOGINPROMPT=LIP/K", (LONG)"ogin:" , /* prompt of remotesite */
"LOGINTIMEOUT=LTO/K/N", (LONG)"\0\0\0\x03" , /* Time to wait for the loginprompt */
"LOGINNAME=LIN/K", NULL , /* Name to answer at A_LIP */
"PASSWORDPROMPT=PWP/K", (LONG)"assword:" , /* prompt for password */
"PASSWORD=PW/K", NULL , /* password */
"SNDLOGINPROMPT=SLIP/K", (LONG)"ogin:" , /* prompt of remotesite */
"SNDLOGINNAME=SLIN/K", NULL , /* Name to answer at A_LIP */
"SNDPASSWORDPROMPT=SPWP/K", (LONG)"assword:" , /* prompt for snd password */
"SNDPASSWORD=SPW/K", NULL , /* snd password */
"LOGINOK=LOK/K", (LONG)"Packet mode" , /* answer for correct login */
"LOGINOKTIMEOUT=LOT/K/N", (LONG)"\0\0\0\x03" , /* Time to wait for the LOK Msg */
"VERBOSE/S", NULL , /* debuginig stuff active */
"TEST/S", NULL , /* local analog loopback */
"NOSERINIT=NSI/S", NULL , /* init. of serial line ? */
"NODTRIGNORE=NDI/S", NULL , /* Do not send AT&D0 AT&D2 */
"REPORTFILE=RPF/K", NULL , /* where to put report ? */
"QUIET/S", NULL , /* No report of conversation */
"STDERR/S", NULL , /* errormessages to * */
"AUTOANSWER=AA/S", NULL , /* take call after hangup */
"NORECONNECT=NRC/S", NULL , /* do not take call while conn. */
"SANADEVICE=SAD/K", (LONG)"Networks/ppp.device" , /* sana device to use */
"SANAUNIT=SAU/K/N", (LONG)"\0\0\0\0" , /* and its unit */
"SANACONFIGFILE=SCF/K", (LONG)"ppp%d.config" , /* name of the sana config file */
"CONNECTSTRING=CS/K", (LONG)"CONNECT?*19200/V42b" , /* part of the std. connectstr. */
"MODEMSETTINGSCONNECT=MSC/K", (LONG)"ATZ1" , /* settings for connect */
"MODEMSETTINGSHANGUP=MSH/K", (LONG)"ATZ1" , /* settings after hang up */
"MODEMQUERYCMD=MQC/K", (LONG)"AT&VI2" , /* cmd to query modemstatus */
"MODEMREADYCMD=MRC/K", (LONG)"AT" , /* Modem should answer with OK */
"MODEMHANGUPCMD=MHC/K", (LONG)"ATH0" , /* Modem cmd to drop connection */
"MODEMCMDOK=MOK/K", (LONG)"OK" , /* Answer from modem if cmd OK */
"MODEMNOCARRIER=MNC/K", (LONG)"NO CARRIER" , /* modemanswer if not carrier */
"MODEMLINEBUSY=MLB/K", (LONG)"BUSY" , /* modemanswer if line busy */
"MODEMLINEDEAD=MLD/K", (LONG)"NO DIALTONE" , /* modemanswer if there is no dt*/
"MODEMRING=MRG/K", (LONG)"RING" , /* incoming call */
"MODEMANYCONNECT=MAC/K", (LONG)"CONNECT?*\n" , /* modemanswer if any connect */
"MODEMAACMD=MAAC/K", (LONG)"ATS0=%d" , /* Set modem to auto answer */
"MODEMOFFLINECMD=MOC/K", (LONG)"+++" , /* Make modem accept commands */
"MODEMONLINECMD=MLC/K", (LONG)"ATO" , /* Make modem online again */
"MODEMTESTCMD=MTC/K", (LONG)"AT&T1" , /* Make modem loopback */
"MODEMTESTOFFCMD=MTO/K", (LONG)"AT&T0" , /* Make modem stop loopback */
"MODEMTOFFHOOKCMD=MOH/K", (LONG)"ATA" , /* Make modem stop loopback */
"GIVEALLSETTINGS=ALL=GAS/S", NULL , /* show all defaults */
NULL ,
NULL
}; /* END of list */
UBYTE *PNAdeflt[] = { "ATDS1", NULL };
int
main(int argc, BYTE **argv)
{
int result = 20;
/* resurce pointers and resurce openflags: */
struct MsgPort *sanaport = NULL;
struct IOSana2Req *sanaIOReq = NULL;
struct MsgPort *serialport = NULL;
struct MsgPort *timeport = NULL;
struct RDArgs *rdclargs = NULL;
struct RDArgs *rdenvargs = NULL;
UBYTE *varbuf = NULL;
LONG sanaopenerr = TRUE;
LONG seropenerr = TRUE;
LONG timeopenerr = TRUE;
/* flags */
BOOL putOnline = FALSE;
BOOL giveusage = FALSE;
BOOL giveDefault = FALSE;
struct SP serpara; /* serial parameters from of sana device (ppp0.config) */
UBYTE hostname[30]; /* stringbuffer */
UBYTE * template;
LONG argd[A_END + 1];
UBYTE **pn; /* array of phonenumbers */
prgname = argv[0];
if (((struct Library *)DOSBase)->lib_Version < 37 )
return(200);
if (!unique(serialport))
return (4);
if ( ! (varbuf = AllocMem(VARBUFSIZE, MEMF_CLEAR|MEMF_PUBLIC) ) || ! (template = AllocMem(TEMPLATESIZE, MEMF_CLEAR|MEMF_PUBLIC) ) )
CUP("Error allocating memory", 51);
giveDefault = (argc > 1 && ABBREV(argv[1], "DE") );
initDefaultsAndTemplate(template);
if ( strlen(template) > TEMPLATESIZE - 50 )
CUP("Template buffer to small", 52);
pn = PNAdeflt;
/* check environment variable: */
if ( GetVar( "DIALUP", varbuf, VARBUFSIZE, 0 ) != -1 )
{ /* parse env:dialup */
if ( ! ( rdenvargs = AllocDosObject( DOS_RDARGS, NULL) ) )
CUP("Can't allocate DosObject for reading args", 50);
rdenvargs->RDA_Source.CS_Buffer = varbuf;
rdenvargs->RDA_Source.CS_Length = VARBUFSIZE;
rdenvargs->RDA_Source.CS_CurChr = 0;
/* ReadArgs() requires that the line be null-terminated or funny things happen. */
strcat(varbuf, "\n");
if( !ReadArgs( template, arg, rdenvargs ) )
{
Fault(IoErr(), prgname, varbuf, VARBUFSIZE);
CUP1("Error parsing environment variable 'DIALUP':\n%s", varbuf, 20);
}
if ( arg[A_PN] )
pn = (UBYTE **)arg[A_PN]; /* save pns for next call to ReadArgs() */
}
adjustdefs();
if ( giveDefault )
if ( !initDefaultsTemplate(template, argd) )
CUP("MAXARGNAMELEN to small!", 53);
/* parse for command line for paramters or defaultkeywords: */
if ( ! ( rdclargs = ReadArgs(template, giveDefault ? argd : arg, NULL ) ) )
{
Fault(IoErr(), prgname, varbuf, VARBUFSIZE);
CUP1("Error parsing command line.\n%s", varbuf, 20);
};
if ( template ) { FreeMem( template, TEMPLATESIZE );
template = NULL; };
adjustdefs();
if ( !arg[A_PN] )
arg[A_PN] = (LONG)pn; /* corrects a Bug in Readargs(): /M arrays ignore preset defaults :-( */
if ( !arg[A_LIN] )
if ( GetVar( "HOSTNAME", hostname, 30, 0 ) != -1 )
arg[A_LIN] = (LONG)hostname;
if ( giveDefault )
{
showdefaults(argd);
result = 0;
}
else
{ /* now one indent level is missing! (I'm lazy *and* don't like goto's :) */
if ( arg[A_STE] || IsInteractive( Input() ) )
if ( !( mystderr = Open("*", MODE_OLDFILE) ) )
CUP("Sorry for the requester,\nbut: Unable to open '*' (stderr)!\n", 99);
if ( !arg[A_LIN] && strcmp( (UBYTE *) arg[A_LIP], "" ) )
CUP(" Please specify paramter LOGINNAME=LIN\n or setenv 'HOSTNAME' instead! (To skip \n login chat specify LOGINPROMPT=LIP \"\".) ", 35)
if ( !arg[A_PW] && strcmp( (UBYTE *)arg[A_PWP], "" ) && strcmp( (UBYTE *)arg[A_LIP], "" ) )
CUP(" Please specify paramter PASSWORD=PW!\n (To skip password chat specify\n PASSWORDPROMPT=PWP \"\") ", 36)
/* where to put the report of serial communication and sana status */
if ( ! arg[A_RPF] )
{
if ( !arg[A_QUIET] )
repfile = Output();
}
else
if ( ! ( repfile = Open((UBYTE *)arg[A_RPF], MODE_NEWFILE ) ) )
CUP1("Unable to create reportfile '%s'", arg[A_RPF], 21);
if ( ! ReadConfig( (UBYTE *)arg[A_SCF], *(LONG *)arg[A_SAU], &serpara) )
CUP("Error reading sana configuration file!", 22);
if ( ( arg[A_AA] || !arg[A_NRC] ) && serpara.listen2CD )
msg("\
Warning: If you don't remove the 'CD' paramter from\n\
the sana configuration file, you will'\n\
have to manually 'online' the sana device \n\
on incomming calls.\n\
(To avoid this warning use NORECONNECT or NRC)",
*(LONG *)arg[A_SAU]);
/* open ppp.device */
if ( ! ( sanaport = CreateMsgPort() ) )
CUP("Unable to create message port for sana device.", 23);
if ( ! ( sanaIOReq = CreateIORequest(sanaport, sizeof(*sanaIOReq) ) ) )
CUP ("Unable to create IORequest for sanal line.", 24);
if ( sanaopenerr = OpenDevice((UBYTE *)arg[A_SAD], *(LONG *)arg[A_SAU], (struct IORequest *)sanaIOReq, 0L))
CUP1("Unable to open sana device '%s'.",arg[A_SAD], 25);
/************************************************/
/* Sana ONLINE */
/************************************************/
if ( ABBREV((UBYTE *)arg[A_CMD], "ON" ) )
{
putOnline = TRUE;
result = 0;
}
/**********************************************/
/* Sana OFFLINE */
/**********************************************/
else
if ( ABBREV((UBYTE *)arg[A_CMD], "OF" ) )
{
sanaIOReq->ios2_Req.io_Command = S2_OFFLINE;
if ( DoIO( (struct IORequest *)sanaIOReq) )
CUP("Error in making sana device offline.", 26);
if ( repfile )
Write(Output(), WS("Sana offline\n"));
putOnline = FALSE;
result = 0;
}
else
{
/* now another indent level more missing! (I'm lazy *and* don't like goto's :) */
/* get receivebuffer */
if ( ! ( rxbuffer = AllocMem(RXBUFSIZE, 0) ) )
CUP("Unable get memory for receive buffer.", 27);
/* open timer device */
if ( ! ( timeport = CreateMsgPort() ) )
CUP("Unable to create message port for timer device.", 28);
if ( ! ( timereq = (struct timerequest *)CreateIORequest( timeport, sizeof( struct timerequest ) ) ) )
CUP ("Unable to create IORequest for timer device.", 29);
if ( timeopenerr = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timereq, 0L) )
CUP("Timer device did not open.", 30);
/* open serial device */
if ( ! ( serialport = CreateMsgPort() ) )
CUP("Unable to create message port for serial line.", 31);
serialport->mp_Node.ln_Name = SERPORTNAME;
serialport->mp_Node.ln_Pri = -1;
AddPort(serialport);
if ( ! ( serialIOReq = (struct IOExtSer *) CreateIORequest( serialport, sizeof(struct IOExtSer) ) ) )
CUP ("Unable to create IORequest for serial line.", 32);
serialIOReq->io_SerFlags = 0;
if ( seropenerr = OpenDevice(serpara.serDevName, serpara.serUnit, (struct IORequest *)serialIOReq, 0) )
{
sanaIOReq->ios2_Req.io_Command = S2_OFFLINE;
if ( repfile )
Write(Output(), WS("Sana offline\n"));
if ( DoIO( (struct IORequest *)sanaIOReq) )
CUP("Error in sana offline for opening serial device.", 33);
if ( seropenerr = OpenDevice(serpara.serDevName, serpara.serUnit, (struct IORequest *)serialIOReq, 0) )
CUP("Serial device did not open (even with slip offline!).", 34 );
putOnline = TRUE;
}
if ( !initSerialLine(&serpara) )
CUP("Error initalizing serial line", 39 )
result = 10; /* so far, so good .. No fatal errors anymore */
/**********************************************/
/* TAKE */
/**********************************************/
if ( ABBREV((UBYTE *)arg[A_CMD], "TA" ) )
{
if ( carrier() )
putOnline = TRUE;
else
{
if ( (result = take( varbuf ) < 10 ) )
putOnline = TRUE;
else /* something went wrong */
{ /* hangup if we are running without user */
if ( ! IsInteractive( Input() ) )
if ( ! hangup(varbuf) )
hangup(varbuf);
if ( ! arg[A_QUIET] )
msg("Failed to take call!");
}
}
}
/**********************************************/
/* CONNECT, TOGGLE */
/**********************************************/
else
if ( ( ABBREV((UBYTE *)arg[A_CMD], "TO" ) && !carrier() ) || ABBREV((UBYTE *)arg[A_CMD], "CO" ) )
{
if ( carrier() )
{
if ( !arg[A_QUIET] )
msg("Modem is already online!\n(carrier detected)");
result = 5;
}
else
{
if ( connect(varbuf) )
{
putOnline = TRUE;
result = 1;
}
else /* something went wrong */
{
if ( ! IsInteractive( Input() ) )
if ( ! hangup(varbuf) )
hangup(varbuf);
if ( ! arg[A_QUIET] )
msg("Failed to connect!");
}
}
}
/**********************************************/
/* HANGUP and TOGGLE */
/**********************************************/
else
if ( ( ABBREV((UBYTE *)arg[A_CMD], "TO" ) && carrier() ) || ( ABBREV((UBYTE *)arg[A_CMD], "HA" ) ) )
{
if ( hangup(varbuf) )
result = 0;
if ( !arg[A_QUIET] && ( result >= 10 || carrier() ) )
msg("Failed to disconnect!");
else
{
if ( arg[A_AA] )
putOnline = TRUE; /* put online after hangup for taking incomming calls */
else
putOnline = FALSE; /* put offline after hangup */
}
}
/**********************************************/
/* QUERY modem */
/**********************************************/
else
if ( ABBREV((UBYTE *)arg[A_CMD], "QU" ) )
{
if ( query(varbuf) )
result = 2;
}
/**********************************************/
/* CARRIER DETECT and make online if present */
/**********************************************/
else
if ( ABBREV((UBYTE *)arg[A_CMD], "CD" ) || ABBREV((UBYTE *)arg[A_CMD], "CARRIERDETECT" ) )
{
if ( carrier() )
{
putOnline = TRUE;
result = 5;
}
else
{
putOnline = FALSE;
result = 0;
}
}
/**********************************************/
/* CHECK for carrier */
/**********************************************/
else
if ( ABBREV((UBYTE *)arg[A_CMD], "CH" ) )
{
result = carrier() ? 5 : 0;
}
/*********/
/* Usage */
/*********/
else
giveusage = TRUE;
};
};
cleanup:
if ( ! seropenerr )
{
if ( result >= 10 )
DeleteVar( "SLIPCARRIER", GVF_GLOBAL_ONLY );
else
SetVar( "SLIPCARRIER", carrier() ? "ON" : "OFF" , -1, GVF_GLOBAL_ONLY );
CloseDevice((struct IORequest*)serialIOReq);
}
if ( ! sanaopenerr )
{
if ( putOnline )
{
sanaIOReq->ios2_Req.io_Command = S2_ONLINE;
if ( DoIO((struct IORequest *)sanaIOReq) )
result = 10;
else
if ( repfile )
Write(Output(), WS("Sana online\n"));
}
CloseDevice((struct IORequest*)sanaIOReq);
};
if ( ! timeopenerr)
{
if ( ! CheckIO( (struct IORequest *)timereq ) )
AbortIO( (struct IORequest *)timereq );
CloseDevice( (struct IORequest *)timereq );
}
if ( serialport )
{
if ( serialport->mp_Node.ln_Name )
RemPort(serialport);
DeleteMsgPort(serialport);
};
if ( serialIOReq ) DeleteIORequest((struct IORequest*)serialIOReq);
if ( sanaport ) DeleteMsgPort(sanaport);
if ( sanaIOReq ) DeleteIORequest((struct IORequest*)sanaIOReq);
if ( timeport ) DeleteMsgPort( timeport );
if ( timereq ) DeleteIORequest( timereq );
/* usage after closing serial device and (maybe) online of sana: */
if ( giveusage ) msg("%s\n\n\
Unknown command '%s'. Valid Commands are:\n\n\
COnnect, HAngup, TOggle, TAke, QUery,\n\
ONline, OFfline, CarrierDetect and CHeck.\n\
The default COMMAND is TOGGLE (CONNECT/HANGUP).\n\
\n\
To get the parameter template use '%s ?'.\n\
\n\
TEST does a modem internal loopback test and no real connect.\n\
RINGS does only take effect after HANGUP with AUTOANSWER.\n\
Use COnnect QUIET before every netappli. to ensure connection.\n\
Add '%s CD' to user-startup to online after reboot\n\n\
To get the paramter defaults use %s DEfault <parameter>|ALL",
&version[6], (UBYTE *)arg[A_CMD], prgname, prgname, prgname);
if ( rxbuffer )
FreeMem( rxbuffer, RXBUFSIZE );
if ( arg[A_RPF] && repfile )
Close( repfile );
if ( rdclargs )
FreeArgs( rdclargs );
if ( rdenvargs )
{
FreeArgs( rdenvargs );
FreeDosObject(DOS_RDARGS, rdenvargs);
};
if ( varbuf )
FreeMem( varbuf, VARBUFSIZE );
if ( template )
FreeMem( template, TEMPLATESIZE );
if ( mystderr )
Close(mystderr);
return( result );
}
void
adjustdefs()
{
if ( arg[A_SCF] == argtab[A_SCF].deflt && ( strstr( (UBYTE *)arg[A_SAD], "ppp" ) || strstr( (UBYTE *)arg[A_SAD], "PPP" ) ) )
arg[A_SCF] = (LONG)"ppp%d.config";
if ( arg[A_VERBOSE] && !arg[A_RPF] ) arg[A_RPF] = (LONG)"CON:50/50/400/200/Dialup(VEROSE)/CLOSE/INACTIVE/WAIT";
}